{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Part 8 - পরিচয় পরিকল্পনা সমূহ (Introduction to Plans)\n",
    "\n",
    "\n",
    "### প্রসঙ্গ (Context)\n",
    "\n",
    "আমরা এখানে এমন একটি বিষয় প্রবর্তন করি যা শিল্প ফেডারেটড লার্নিং: পরিকল্পনাটি স্কেল করার জন্য অত্যন্ত গুরুত্বপূর্ণ। এটি নাটকীয়ভাবে ব্যান্ডউইথের ব্যবহার হ্রাস করে, অ্যাসিনক্রোনাস স্কিমগুলির অনুমতি দেয় এবং দূরবর্তী ডিভাইসগুলিতে আরও স্বায়ত্তশাসন দেয়। পরিকল্পনার মূল ধারণাটি কাগজে পাওয়া যাবে [Towards Federated Learning at Scale: System Design](https://arxiv.org/pdf/1902.01046.pdf), তবে এটি পাইসাইফ্ট লাইব্রেরিতে আমাদের প্রয়োজনের সাথে খাপ খাইয়ে নিয়েছে।\n",
    "\n",
    "একটি পরিকল্পনা ঠিক একটি ফাংশনের মতো মশাল ক্রিয়াকলাপগুলির ক্রম সংরক্ষণ করার উদ্দেশ্যে তৈরি করা হয়েছিল, তবে এটি অপারেশনগুলির এই ক্রমটি প্রত্যন্ত কর্মীদের কাছে প্রেরণ এবং এটির একটি রেফারেন্স রাখতে দেয়। এইভাবে, দূরবর্তী অবস্থান থেকে এই ক্রম গণনা করা $n$ পাঠানোর পরিবর্তে পয়েন্টারগুলির মাধ্যমে কিছু দূরবর্তী ইনপুটটিতে ক্রিয়াকলাপ $n$ পরিকল্পনার উল্লেখ এবং পয়েন্টারগুলির সাথে একক বার্তা প্রেরণের জন্য আপনার এখন যে বার্তাগুলি প্রয়োজন সেগুলি। আপনি আপনার ফাংশন সহ টেনারগুলিও সরবরাহ করতে পারেন (যা আমরা কল করি _state tensors_ ) বর্ধিত কার্যকারিতা আছে। পরিকল্পনাগুলি আপনি যে কোনও ফাংশন প্রেরণ করতে পারেন তার মতো দেখা যায়, বা এমন কোনও শ্রেণীর মতো যা প্রেরণ এবং দূরবর্তীভাবে কার্যকর করা যায়। অতএব, উচ্চ স্তরের ব্যবহারকারীদের জন্য, পরিকল্পনার ধারণাটি অদৃশ্য হয়ে যায় এবং এর পরিবর্তে একটি যাদু বৈশিষ্ট্য রয়েছে যা দূরবর্তী শ্রমিকদের সিক্যুয়ালি টর্চ ফাংশনগুলি সহ নির্বিচারে ফাংশনগুলি প্রেরণ করতে দেয়।\n",
    "\n",
    "একটি বিষয় লক্ষ্য করুন যে ফাংশনগুলির শ্রেণি যা আপনি পরিকল্পনাগুলিতে রূপান্তর করতে পারেন তা কেবল একচেটিয়াভাবে টুকরা টর্চ ক্রিয়াকলাপগুলির মধ্যে সীমাবদ্ধ। এটি যেমন নির্দিষ্ট যৌক্তিক কাঠামো বাদ দেয়  `if`, `for` এবং `while` বিবৃতি, এমনকি যদি আমরা শীঘ্রই প্রায় কাজ করতে কাজ করছি। _সম্পূর্ণরূপে সুনির্দিষ্ট হওয়ার জন্য, আপনি এগুলি ব্যবহার করতে পারেন তবে আপনার নেওয়া যৌক্তিক পথটি (প্রথমে `if` মিথ্যা এবং 5 লুপ ইন `for` উদাহরণ স্বরূপ) আপনার পরিকল্পনার প্রথম গণিতে পরবর্তী সমস্ত গণনাগুলির জন্য রাখা হবে, যা আমরা বেশিরভাগ ক্ষেত্রে এড়াতে চাই।_\n",
    "\n",
    "Authors:\n",
    "\n",
    "- Théo Ryffel - Twitter [@theoryffel](https://twitter.com/theoryffel) - GitHub: [@LaRiffle](https://github.com/LaRiffle)\n",
    "- Bobby Wagner - Twitter [@bobbyawagner](https://twitter.com/bobbyawagner) - GitHub: [@robert-wagner](https://github.com/robert-wagner)\n",
    "- Marianne Monteiro - Twitter [@hereismari](https://twitter.com/hereismari) - GitHub: [@mari-linhares](https://github.com/mari-linhares)\t"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "অনুবাদক:\n",
    "\n",
    "- Sourav Das - Twitter: [@adventuroussrv](https://twitter.com/adventuroussrv)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### আমদানি এবং মডেল বিশেষ উল্লেখ (Imports and model specifications)\n",
    "\n",
    "প্রথমে সরকারী আমদানি করি।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "এবং পাইসাইফ্ট সম্পর্কিত নির্দিষ্টগুলির চেয়ে একটি গুরুত্বপূর্ণ নোট সহ: **স্থানীয় কর্মী ক্লায়েন্ট কর্মী হওয়া উচিত নয়(the local worker should not be a client worker.)** *অ ক্লায়েন্ট কর্মীরা বস্তু সংরক্ষণ করতে পারে এবং একটি পরিকল্পনা চালানোর জন্য আমাদের এই দক্ষতার প্রয়োজন.*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import syft as sy  # import the Pysyft library\n",
    "hook = sy.TorchHook(torch)  # hook PyTorch ie add extra functionalities \n",
    "\n",
    "# IMPORTANT: Local worker should not be a client worker\n",
    "hook.local_worker.is_client_worker = False\n",
    "\n",
    "\n",
    "server = hook.local_worker"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আমরা দূরবর্তী কর্মীদের সংজ্ঞা দিই বা _devices_ , রেফারেন্স নিবন্ধে সরবরাহিত ধারণার সাথে সামঞ্জস্যপূর্ণ হতে।\n",
    "আমরা তাদের কিছু তথ্য সরবরাহ করি।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x11 = torch.tensor([-1, 2.]).tag('input_data')\n",
    "x12 = torch.tensor([1, -2.]).tag('input_data2')\n",
    "x21 = torch.tensor([-1, 2.]).tag('input_data')\n",
    "x22 = torch.tensor([1, -2.]).tag('input_data2')\n",
    "\n",
    "device_1 = sy.VirtualWorker(hook, id=\"device_1\", data=(x11, x12)) \n",
    "device_2 = sy.VirtualWorker(hook, id=\"device_2\", data=(x21, x22))\n",
    "devices = device_1, device_2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### বেসিক উদাহরণ (Basic example)\n",
    "\n",
    "আসুন একটি ফাংশন সংজ্ঞায়িত করুন যা আমরা একটি পরিকল্পনায় রূপান্তর করতে চাই। এটি করার জন্য, এটি ফাংশন সংজ্ঞা উপরে একটি সাজসজ্জা যোগ করার মত সহজ!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@sy.func2plan()\n",
    "def plan_double_abs(x):\n",
    "    x = x + x\n",
    "    x = torch.abs(x)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আসুন পরীক্ষা করে দেখুন, হ্যাঁ আমাদের এখন একটি পরিকল্পনা আছে!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plan_double_abs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "একটি পরিকল্পনা ব্যবহার করতে আপনার দুটি জিনিস দরকার: পরিকল্পনাটি তৈরি করা (_আপনি ফাংশনটিতে উপস্থিত ক্রিয়াকলাপের ক্রমটি নিবন্ধ করুন) এবং এটি কোনও কর্মী / ডিভাইসে প্রেরণ করা। ভাগ্যক্রমে আপনি এটি খুব সহজেই করতে পারেন!\n",
    "\n",
    "#### একটি পরিকল্পনা তৈরি (Building a plan)\n",
    "\n",
    "একটি পরিকল্পনা তৈরি করতে আপনাকে এটিকে কিছু ডেটাতে কল করতে হবে।\n",
    "\n",
    "প্রথমে কিছু দূরবর্তী ডেটার জন্য একটি রেফারেন্স পাই: নেটওয়ার্কের মাধ্যমে একটি অনুরোধ প্রেরণ করা হয় এবং একটি রেফারেন্স পয়েন্টারটি ফেরত দেওয়া হয়।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_to_data = device_1.search('input_data')[0]\n",
    "pointer_to_data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আমরা যদি পরিকল্পনাটি বলি তবে এটি অবশ্যই ডিভাইসে দূরবর্তীভাবে কার্যকর করা উচিত `location:device_1`... আমরা ত্রুটি পেয়ে যাব কারণ পরিকল্পনাটি এখনও নির্মিত হয়নি।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plan_double_abs.is_built"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Sending non-built Plan will fail\n",
    "try:\n",
    "    plan_double_abs.send(device_1)\n",
    "except RuntimeError as error:\n",
    "    print(error)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "একটি পরিকল্পনা তৈরি করতে আপনাকে কেবল কল করতে হবে `build` পরিকল্পনার উপর এবং পরিকল্পনাটি কার্যকর করতে প্রয়োজনীয় যুক্তিগুলি পাস করুন (a.k.a কিছু ডেটা)। যখন কোনও পরিকল্পনা তৈরি করা হয় তখন সমস্ত কমান্ড স্থানীয় কর্মী ক্রমান্বয়ে সম্পাদন করে, এবং পরিকল্পনার দ্বারা ক্যাচ করা হয় এবং এর মধ্যে সংরক্ষণ করা হয়`readable_plan`অ্যাট্রিবিউট!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plan_double_abs.build(torch.tensor([1., -2.]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plan_double_abs.is_built"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আমরা যদি এখন পরিকল্পনাটি পাঠানোর চেষ্টা করি এটি কার্যকর হয়!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This cell is executed successfully\n",
    "pointer_plan = plan_double_abs.send(device_1)\n",
    "pointer_plan"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ততক্ষণে টেনেসরের সাথে আমরা প্রেরিত বস্তুর একটি পয়েন্টার পাই। এখানে একে বলা হয় `PointerPlan`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "একটি গুরুত্বপূর্ণ বিষয় মনে রাখবেন যে যখন একটি পরিকল্পনা তৈরি করা হয় তখন আমরা গণনার পূর্বে প্রাক সেট করে থাকি id(s) যেখানে ফলাফল  result(s) সংরক্ষণ করা উচিত এটি ইতিমধ্যে ভার্চুয়াল ফলাফলের একটি রেফারেন্স রাখতে এবং দূরবর্তী ফলাফলটি গণনা করার জন্য অপেক্ষা না করে স্থানীয় গণনা চালিয়ে যাওয়ার জন্য, অবিচ্ছিন্নভাবে কমান্ডগুলি প্রেরণের অনুমতি দেবে একটি বড় অ্যাপ্লিকেশন হ'ল যখন আপনাকে একটি ব্যাচের অন গণনা প্রয়োজন device_1 এবং এই গণনাটি অন্য ব্যাচের গণনা চালু করার জন্য অপেক্ষা করতে চাই না device_2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### দূরবর্তীভাবে একটি পরিকল্পনা চালানো (Running a Plan remotely)\n",
    "\n",
    "আমরা এখন দূরবর্তী অবস্থান থেকে কিছু ডেটারের পয়েন্টার দিয়ে পরিকল্পনার দিকে কল করে পরিকল্পনাটি চালাতে পারি। এই পরিকল্পনাটি দূর থেকে চালিত করার জন্য একটি আদেশ জারি করে, যাতে পরিকল্পনার আউটপুটটির পূর্বনির্ধারিত অবস্থানটিতে এখন ফলাফল থাকে (মনে রাখবেন আমরা গণনার আগে ফলাফলের পূর্বনির্ধারিত অবস্থান)। এটির জন্য একটি একক যোগাযোগের বৃত্তও প্রয়োজন।\n",
    "\n",
    "ফলাফলটি কেবল একটি পয়েন্টার, ঠিক যেমন আপনি যখন কোনও সাধারণ টুকরা টর্চ ফাংশন কল করেন!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_to_result = pointer_plan(pointer_to_data)\n",
    "print(pointer_to_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "এবং আপনি কেবল মানটি আবার জিজ্ঞাসা করতে পারেন।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_to_result.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### একটি কংক্রিট উদাহরণের দিকে (Towards a concrete example)\n",
    "\n",
    "তবে আমরা কী করতে চাই তা হল গভীর এবং সংঘবদ্ধ শিক্ষার পরিকল্পনার প্রয়োগ করা, তাই না? সুতরাং আসুন স্নায়ুবিক নেটওয়ার্কগুলি ব্যবহার করার জন্য আপনি যেমন ইচ্ছা করতে চান তেমন আরও জটিল উদাহরণটি দেখুন।\n",
    "নোট করুন যে আমরা এখন একটি ক্লাসকে পরিকল্পনায় রূপান্তর করছি। এটি করার জন্য, আমরা আমাদের ক্লাস থেকে উত্তরাধিকারী sy.Plan (পরিবর্তে উত্তরাধিকার সূত্রে nn.Module)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Net(sy.Plan):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.fc1 = nn.Linear(2, 3)\n",
    "        self.fc2 = nn.Linear(3, 2)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = self.fc2(x)\n",
    "        return F.log_softmax(x, dim=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "net = Net()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "net"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আসুন কিছু মক ডেটা ব্যবহার করে পরিকল্পনাটি তৈরি করি।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "net.build(torch.tensor([1., 2.]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আমরা এখন পরিকল্পনাটি প্রত্যন্ত শ্রমিকের কাছে প্রেরণ করি"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_to_net = net.send(device_1)\n",
    "pointer_to_net"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আসুন কিছু দূরবর্তী ডেটা উদ্ধার করি"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_to_data = device_1.search('input_data')[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "তারপরে, সিনট্যাক্সটি সাধারণ দূরবর্তী ক্রমিক ক্রিয়াকলাপের মতো, যেমন স্থানীয় প্রয়োগের মতো। তবে ক্লাসিক রিমোট এক্সিকিউশনটির তুলনায় প্রতিটি মৃত্যুদন্ড কার্যকর করার জন্য একক যোগাযোগের রাউন্ড রয়েছে।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_to_result = pointer_to_net(pointer_to_data)\n",
    "pointer_to_result"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "এবং আমরা ফলাফল হিসাবে যথারীতি পেতে!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_to_result.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Et voilà!আমরা দেখেছি কীভাবে স্থানীয় কর্মী (বা সার্ভার) এবং দূরবর্তী ডিভাইসগুলির মধ্যে যোগাযোগ নাটকীয়ভাবে হ্রাস করতে পারে!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### কর্মীদের মধ্যে স্যুইচ করুন (Switch between workers)\n",
    "\n",
    "একটি প্রধান বৈশিষ্ট্য যা আমরা রাখতে চাই তা হ'ল বেশ কয়েকটি শ্রমিকের জন্য একই পরিকল্পনাটি ব্যবহার করা, আমরা যে ডেটা বিবেচনা করছি তা দূরবর্তী ব্যাচের উপর নির্ভর করে আমরা পরিবর্তন করব।\n",
    "বিশেষত, প্রতিবার কর্মী পরিবর্তন করার পরে আমরা পরিকল্পনাটি পুনর্নির্মাণ করতে চাই না। আসুন আমরা দেখুন কিভাবে এটি করি, আমাদের ছোট নেটওয়ার্কের সাথে পূর্ববর্তী উদাহরণটি ব্যবহার করে।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Net(sy.Plan):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.fc1 = nn.Linear(2, 3)\n",
    "        self.fc2 = nn.Linear(3, 2)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = self.fc2(x)\n",
    "        return F.log_softmax(x, dim=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "net = Net()\n",
    "\n",
    "# Build plan\n",
    "net.build(torch.tensor([1., 2.]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "এখানে আমরা স্রেফ কার্যকর করা প্রধান পদক্ষেপগুলি"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_to_net_1 = net.send(device_1)\n",
    "pointer_to_data = device_1.search('input_data')[0]\n",
    "pointer_to_result = pointer_to_net_1(pointer_to_data)\n",
    "pointer_to_result.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "এবং প্রকৃতপক্ষে আপনি একই পরিকল্পনা থেকে অন্যান্য পয়েন্টারপ্লানগুলি তৈরি করতে পারেন, সুতরাং বাক্য বাক্যটি অন্য ডিভাইসে দূরবর্তীভাবে পরিকল্পনা চালানোর জন্য একই"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_to_net_2 = net.send(device_2)\n",
    "pointer_to_data = device_2.search('input_data')[0]\n",
    "pointer_to_result = pointer_to_net_2(pointer_to_data)\n",
    "pointer_to_result.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> দ্রষ্টব্য: বর্তমানে, প্ল্যান ক্লাস সহ, আপনি কেবল একটি একক পদ্ধতি ব্যবহার করতে পারেন এবং আপনাকে এটির নাম \"ফরওয়ার্ড/forward\" রাখতে হবে।"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### ফাংশনগুলি স্বয়ংক্রিয়ভাবে পরিকল্পনা তৈরি করা (Automatically building plans that are functions_\n",
    "\n",
    "ফাংশন জন্য (`@` `sy.func2plan`) আমরা স্পষ্টভাবে কল করার প্রয়োজন ছাড়াই পরিকল্পনাটি স্বয়ংক্রিয়ভাবে তৈরি করতে পারি `build`আসলে তৈরির মুহূর্তে পরিকল্পনা ইতিমধ্যে নির্মিত হয়েছে।\n",
    "\n",
    "এই কার্যকারিতাটি পেতে হলে কোনও পরিকল্পনা তৈরি করার সময় আপনার কেবলমাত্র পরিবর্তন করতে হবে ডাকাডাকিটির সাথে একটি যুক্তি সেট করে `args_shape` যা প্রতিটি যুক্তির আকার যুক্ত তালিকা থাকা উচিত।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@sy.func2plan(args_shape=[(-1, 1)])\n",
    "def plan_double_abs(x):\n",
    "    x = x + x\n",
    "    x = torch.abs(x)\n",
    "    return x\n",
    "\n",
    "plan_double_abs.is_built"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "পরিকল্পনাটি তৈরির জন্য প্রদত্ত আকারের সাথে মক টেনারগুলি তৈরি করতে `args_shape` প্যারামিটারটি অভ্যন্তরীণভাবে ব্যবহৃত হয়।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@sy.func2plan(args_shape=[(1, 2), (-1, 2)])\n",
    "def plan_sum_abs(x, y):\n",
    "    s = x + y\n",
    "    return torch.abs(s)\n",
    "\n",
    "plan_sum_abs.is_built"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "আপনি কার্যগুলিতে রাষ্ট্রের উপাদানগুলি সরবরাহ করতে পারেন!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@sy.func2plan(args_shape=[(1,)], state=(torch.tensor([1]), ))\n",
    "def plan_abs(x, state):\n",
    "    bias, = state.read()\n",
    "    x = x.abs()\n",
    "    return x + bias"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pointer_plan = plan_abs.send(device_1)\n",
    "x_ptr = torch.tensor([-1, 0]).send(device_1)\n",
    "p = pointer_plan(x_ptr)\n",
    "p.get()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "এ সম্পর্কে আরও জানার জন্য, আপনি টিউটোরিয়ালে প্রোটোকল সহ প্ল্যানগুলি কীভাবে ব্যবহার করবেন তা আবিষ্কার করতে পারেন Part 8 bis!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### গিটহাবে পাইসিফ্ট কে স্টার দিন (Star PySyft on GitHub)\n",
    "\n",
    "আমাদের সম্প্রদায়কে সাহায্য করার সবচেয়ে সহজ উপায় হল রিপোসিটোরি গুলোতে ষ্টার করা\n",
    " এটি আমরা যে অসাধারণ সরঞ্জামগুলি তৈরি করছি তার সচেতনতা বাড়াতে সহায়তা করে।\n",
    "\n",
    "- [Star PySyft](https://github.com/OpenMined/PySyft)\n",
    "\n",
    "### গিটহাবে আমাদের টিউটোরিয়ালগুলি চয়ন করুন (Pick our tutorials on GitHub!)\n",
    "\n",
    "ফেডারেটেড এবং প্রাইভেসি-প্রিজারভেভিং লার্নিংয়ের চেহারা কেমন হওয়া উচিত এবং আমরা এটির জন্য ইটগুলি কীভাবে তৈরি করছি সে সম্পর্কে আরও ভাল ধারণা পেতে আমরা সত্যিই দুর্দান্ত টিউটোরিয়াল তৈরি করেছি।\n",
    "\n",
    "- [Checkout the PySyft tutorials](https://github.com/OpenMined/PySyft/tree/master/examples/tutorials)\n",
    "\n",
    "\n",
    "### আমাদের স্ল্যাক যোগ দিন (Join our Slack!)\n",
    "\n",
    "সর্বশেষতম অগ্রগতিতে আপ টু ডেট রাখার সর্বোত্তম উপায় হ'ল আমাদের সম্প্রদায়ে যোগদান করা! আপনি ফর্মটি পূরণ করে এটি করতে পারেন\n",
    "\n",
    "- [Join slack.openmined.org](http://slack.openmined.org)\n",
    "\n",
    "### একটি কোড প্রকল্পে যোগদান করুন! (Join a Code Project!)\n",
    "\n",
    "আমাদের সম্প্রদায়ে অবদান রাখার সর্বোত্তম উপায় হ'ল কোড অবদানকারী হয়ে উঠুন! আপনি যদি \"ওয়ান অফ\" মিনি-প্রকল্পগুলি শুরু করতে চান আপনি পাই সাইফ্ট গিটহাব ইস্যু পৃষ্ঠাতে এবং চিহ্নিত বিষয়গুলির জন্য অনুসন্ধান করতে পারেন `Good First Issue`.\n",
    "\n",
    "- [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n",
    "\n",
    "### দান করুন (Donate)\n",
    "\n",
    "আপনার যদি আমাদের কোডবেসে অবদান রাখার সময় না থাকে তবে তবুও সমর্থন দিতে চান, আপনি আমাদের ওপেন কালেক্টিভেরও Backer হয়ে উঠতে পারেন। সমস্ত অনুদান আমাদের ওয়েব হোস্টিং এবং অন্যান্য সম্প্রদায় ব্যয় যেমন হ্যাকাথনস এবং মেটআপগুলির (hackathons and meetups!) দিকে যায়!\n",
    "\n",
    "- [Donate through OpenMined's Open Collective Page](https://opencollective.com/openmined)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
